import { asyncRoutes, constantRoutes } from '@/router'

const SET_ROUTES = 'SET_ROUTES';

/**
 * 是否存在该权限
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => {
      // 首先判断路由的名字在菜单中是否存在
      if (route.meta.title === role.name) {
        // 带上排序的下标
        route.meta.order = role.order;
        return true;
      } else {
        return false;
      }
    })
  } else {
    return true
  }
}

/**
 * 过滤权限
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
function filterAsyncRoutes(routes, roles) {
  const res = []
  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

/**
 * 对动态路由进行排序
 * @param {import("vue-router").RouteConfig[]} routes
 */
function sortAsyncRoutes(routes) {
  // 首先对子路由进行排序
  for (let i = 0; i < routes.length; i++) {
    if (routes[i].children && routes[i].children.length > 0) {
      routes[i].children = sortAsyncRoutes(routes[i].children);
    }
  }

  // 最后对根路由排序
  // 从小到大排序
  return routes.sort((a, b) => {
    // 简单来说就是a.meta.order是否存在，不存在就排在最后
    const val1 = a.meta ? (a.meta.order ? a.meta.order : Number.MAX_SAFE_INTEGER) : Number.MAX_SAFE_INTEGER;
    const val2 = b.meta ? (b.meta.order ? b.meta.order : Number.MAX_SAFE_INTEGER) : Number.MAX_SAFE_INTEGER;
    return val1 - val2
  });
}

const state = {
  routes: [],
  addRoutes: [],
}

const mutations = {
  [SET_ROUTES]: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {

  /**
  * 是否已经获取了权限代码
  * @param {*} param0
  * @returns
  */
  hasRoles({ state }) {
    const { meunCode, atomicCode } = state;
    return meunCode.length !== 0 && atomicCode.length !== 0;
  },

  async generateRoutes({ commit }, roles) {

    // 权限过滤
    const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
    // 路由重排
    const accessedSortedRoutes = sortAsyncRoutes(accessedRoutes);
    commit(SET_ROUTES, accessedSortedRoutes);
    return accessedRoutes
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
